import random


class Address:
    """地址类，包含国家、省份、街道和门牌号信息"""

    def __init__(self, country, province, street, house_number):
        self.country = country
        self.province = province
        self.street = street
        self.house_number = house_number

    def __str__(self):
        return f"{self.country} {self.province} {self.street} {self.house_number}"


class User:
    """用户类，包含账号、账户类型、姓名、密码、地址、存款余额和开户行信息"""

    def __init__(self, account_id, account_type, name, password, address, balance, bank_name):
        self.account_id = account_id
        self.account_type = account_type  # 1: 一类账户(金卡), 2: 二类账户(普通卡)
        self.name = name
        self.password = password  # 存储为整数
        self.address = address  # 地址对象
        self.balance = balance  # 存款余额，整数
        self.bank_name = bank_name  # 开户行名称

        # 根据账户类型设置转账限额
        if self.account_type == 1:
            self.transfer_limit = 50000  # 一类账户最大转账额5万
        else:
            self.transfer_limit = 20000  # 二类账户最大转账额2万

    def __str__(self):
        account_type_str = "一类账户(金卡)" if self.account_type == 1 else "二类账户(普通卡)"
        return (f"当前账号：{self.account_id}, 姓名：{self.name}, 账户类型：{account_type_str}, "
                f"密码: {self.password}, 余额：{self.balance}元, 用户居住地址：{self.address}, "
                f"当前账户的开户行：{self.bank_name}, 最大转账限额：{self.transfer_limit}元")


class Bank:
    """银行类，管理用户库和提供各种银行业务功能"""

    def __init__(self, bank_name):
        self.bank_name = bank_name
        self.users = {}  # 存储用户，键为账号，值为用户对象
        self.max_users = 100  # 最大用户数量

    def generate_account_id(self):
        """生成8位数字的随机账号"""
        return str(random.randint(10000000, 99999999))

    def open_account(self, account_type, name, password, address, initial_balance):
        """
        开户功能
        返回值：1：成功，2：用户已存在（实际是账号已存在），3：用户库已满
        """
        # 检查账户类型是否有效
        if account_type not in [1, 2]:
            print("无效的账户类型！")
            return 0

        # 检查用户库是否已满
        if len(self.users) >= self.max_users:
            return 3

        # 生成账号并确保不重复
        while True:
            account_id = self.generate_account_id()
            if account_id not in self.users:
                break

        # 创建新用户并添加到用户库
        new_user = User(
            account_id=account_id,
            account_type=account_type,
            name=name,
            password=password,
            address=address,
            balance=initial_balance,
            bank_name=self.bank_name
        )

        self.users[account_id] = new_user
        print(f"您的账号是: {account_id}，请妥善保管！")
        return 1

    def deposit(self, account_id, amount):
        """
        存钱功能
        返回值：布尔类型，True表示成功，False表示失败
        """
        if account_id not in self.users:
            return False

        # 确保存款金额为正数
        if amount <= 0:
            return False

        self.users[account_id].balance += amount
        return True

    def withdraw(self, account_id, password, amount):
        """
        取钱功能
        返回值：0：正常，1：账号不存在，2：密码不对，3：钱不够，4：超过取款限额
        """
        # 检查账号是否存在
        if account_id not in self.users:
            return 1

        user = self.users[account_id]

        # 检查密码是否正确
        if user.password != password:
            return 2

        # 检查金额是否为正数
        if amount <= 0:
            return 3

        # 检查是否超过账户类型的转账(取款)限额
        if amount > user.transfer_limit:
            return 4

        # 检查余额是否足够
        if user.balance < amount:
            return 3

        # 执行取钱操作
        user.balance -= amount
        return 0

    def transfer(self, from_account, to_account, password, amount):
        """
        转账功能
        返回值：0：正常，1：账号不对，2：密码不对，3：钱不够，4：超过转账限额
        """
        # 检查转出和转入账号是否都存在
        if from_account not in self.users or to_account not in self.users:
            return 1

        # 检查转出账号和转入账号是否相同
        if from_account == to_account:
            print("不能向自己的账户转账！")
            return 1

        # 检查转出账号密码是否正确
        from_user = self.users[from_account]
        if from_user.password != password:
            return 2

        # 检查转账金额是否合法
        if amount <= 0:
            return 3

        # 检查是否超过账户类型的转账限额
        if amount > from_user.transfer_limit:
            return 4

        # 检查余额是否足够
        if from_user.balance < amount:
            return 3

        # 执行转账操作
        from_user.balance -= amount
        self.users[to_account].balance += amount
        return 0

    def query_account(self, account_id, password):
        """查询账户信息功能"""
        # 检查账号是否存在
        if account_id not in self.users:
            print("该用户不存在。")
            return

        user = self.users[account_id]

        # 检查密码是否正确
        if user.password != password:
            print("密码不正确。")
            return

        # 打印用户信息
        print(user)


class ATM:
    """ATM界面类，提供用户交互界面"""

    def __init__(self, bank):
        self.bank = bank
        self.running = True

    def display_menu(self):
        """显示主菜单"""
        print("\n===== 中国农业银行账户管理系统 =====")
        print("1. 开户")
        print("2. 存钱")
        print("3. 取钱")
        print("4. 转账")
        print("5. 查询账户")
        print("6. 退出")
        print("===================================")

    def handle_open_account(self):
        """处理开户业务"""
        print("\n----- 开户 -----")
        try:
            account_type = int(input("请输入账户类型(1-一类账户(金卡), 2-二类账户(普通卡)): "))
            name = input("请输入姓名: ")
            password = int(input("请设置6位数字密码: "))
            if len(str(password)) != 6:
                print("密码必须是6位数字！")
                return

            # 输入地址信息
            country = input("请输入国家: ")
            province = input("请输入省份: ")
            street = input("请输入街道: ")
            house_number = input("请输入门牌号: ")
            address = Address(country, province, street, house_number)

            initial_balance = int(input("请输入初始存款金额: "))
            if initial_balance < 0:
                print("初始存款不能为负数！")
                return

            # 调用银行开户功能
            result = self.bank.open_account(account_type, name, password, address, initial_balance)

            # 处理开户结果
            if result == 1:
                print("开户成功！")
            elif result == 2:
                print("开户失败：用户已存在")
            elif result == 3:
                print("开户失败：用户库已满")

        except ValueError:
            print("输入错误，请确保输入正确的格式！")

    def handle_deposit(self):
        """处理存钱业务"""
        print("\n----- 存钱 -----")
        try:
            account_id = input("请输入账号: ")
            amount = int(input("请输入存款金额: "))

            if amount <= 0:
                print("存款金额必须为正数！")
                return

            result = self.bank.deposit(account_id, amount)

            if result:
                print(f"存款成功！当前余额: {self.bank.users[account_id].balance}元")
            else:
                print("存款失败：账号不存在")

        except ValueError:
            print("输入错误，请确保输入正确的格式！")

    def handle_withdraw(self):
        """处理取钱业务"""
        print("\n----- 取钱 -----")
        try:
            account_id = input("请输入账号: ")
            password = int(input("请输入密码: "))
            amount = int(input("请输入取款金额: "))

            if amount <= 0:
                print("取款金额必须为正数！")
                return

            result = self.bank.withdraw(account_id, password, amount)
            user = self.bank.users.get(account_id)

            if result == 0:
                print(f"取款成功！当前余额: {user.balance}元")
            elif result == 1:
                print("取款失败：账号不存在")
            elif result == 2:
                print("取款失败：密码不对")
            elif result == 3:
                print("取款失败：余额不足")
            elif result == 4:
                print(f"取款失败：超过最大取款限额({user.transfer_limit}元)")

        except ValueError:
            print("输入错误，请确保输入正确的格式！")

    def handle_transfer(self):
        """处理转账业务"""
        print("\n----- 转账 -----")
        try:
            from_account = input("请输入转出账号: ")
            to_account = input("请输入转入账号: ")

            # 检查是否是向自己转账
            if from_account == to_account:
                print("不能向自己的账户转账！")
                return

            password = int(input("请输入转出账号密码: "))
            amount = int(input("请输入转账金额: "))

            if amount <= 0:
                print("转账金额必须为正数！")
                return

            result = self.bank.transfer(from_account, to_account, password, amount)
            user = self.bank.users.get(from_account)

            if result == 0:
                print(f"转账成功！转出账户当前余额: {user.balance}元")
            elif result == 1:
                print("转账失败：账号不存在")
            elif result == 2:
                print("转账失败：密码不对")
            elif result == 3:
                print("转账失败：余额不足")
            elif result == 4:
                print(f"转账失败：超过最大转账限额({user.transfer_limit}元)")

        except ValueError:
            print("输入错误，请确保输入正确的格式！")

    def handle_query(self):
        """处理查询账户业务"""
        print("\n----- 查询账户 -----")
        try:
            account_id = input("请输入账号: ")
            password = int(input("请输入密码: "))
            self.bank.query_account(account_id, password)
        except ValueError:
            print("输入错误，请确保输入正确的格式！")

    def run(self):
        """运行ATM系统"""
        print("欢迎使用中国农业银行账户管理系统！")
        while self.running:
            self.display_menu()
            try:
                choice = int(input("请选择业务(1-6): "))
                if choice == 1:
                    self.handle_open_account()
                elif choice == 2:
                    self.handle_deposit()
                elif choice == 3:
                    self.handle_withdraw()
                elif choice == 4:
                    self.handle_transfer()
                elif choice == 5:
                    self.handle_query()
                elif choice == 6:
                    self.running = False
                    print("感谢使用，再见！")
                else:
                    print("无效的选择，请重新输入！")
            except ValueError:
                print("输入错误，请输入数字1-6选择业务！")


if __name__ == "__main__":
    # 创建银行实例
    bank = Bank("中国农业银行的昌平沙河支行")
    # 创建ATM实例并运行
    atm = ATM(bank)
    atm.run()
